//加热风扇控制, 排气风扇控制, 点火控制

#include "App_Main.h"
#include "pid.h"
#include "ADC_Model.h"
#include <stdlib.h>
#define LowTempThreshold 120 //华氏度的判断低温阈值
#define TempSet_Min 180      //设定值最小值
#define HEAT_450 450

extern bool filter_fun;
uint16_t PID_T_1s = 0;
int32_t grill_temperature = 0;
float pid_data = 0;
stc_pi_t pid_PI;
int feed_stop_time = 0;
uint32_t feed_stop_time_int = 0;
//uint16_t Start_Temp = 100;
uint32_t feed_on_time = 0;
uint32_t millis_10ms = 0;
extern int32_t temp_filter_time;//时间滤波
stc_pid_para_t pid_para_t={
		.i32Q12_Kp = 0.20,
		.i32Q12_Ki = 0.01,
		.i32Q12_Kd = 0.60,
		.i32Q27_OutMin = 6,
		.i32Q27_OutMax = 60,
	};
extern uint16_t temp_set_updata;
extern int temp_diff;
//温度设定值
uint16_t temp_set = 180; //= Temp_Set_Smoke; //默认 Smoke档位

enum
{
    DISP_POWER_UP = 0,
    DISP_STAND_BY,
    DISP_MAIN_MODE,
    DISP_SET_TIMER_MODE,
    DISP_SET_PROBEALARM_MODE,
    DISP_GRILLRUNNING_MODE,
    DISP_SHUTDOWN_MODE,
    DISP_SysSelfTest_MODE,
} DisplayModeEnum;
uint8_t DisplayMode;
struct
{
    uint8_t SYS_ERROR : 1;
    uint8_t SYS_STANDBY : 1;
    uint8_t SMOKE_SEL_PRESSED : 1; //RTD_SEL_PRESSED
    uint8_t KEY_PRESSED : 1;
    uint8_t TEMP_MODE_SWITCHED : 1;
    uint8_t DISP_PROBE_STATE : 1;
    uint8_t SELF_TEST_EN : 1;
    uint8_t DISP_TIMER_STATE : 1;
} flag;
uint16_t ExhaustFanClock = 0; //倒计时 10min, Tick 1s, 允许数据溢出
uint16_t PowerDown_Clock = 600; //关机倒计时 10min, Tick 1s
uint16_t Tick_1S_Count = 100; //默认上电 100s, 1s计数1次 //Changed this for the initial PID compute time is not less than 0
uint16_t Tick_10mS_Count = 0; //Tick 10ms
uint16_t Smake_10mS_Count = 0; //Tick 10ms
uint16_t Smake_Auger_ON = 0;
uint16_t Smake_Auger_OFF = 0;
uint16_t Smake_Enable = 0;
const uint8_t UPDATE_DISPLAY = 100; //2;  //DW: Changed to update Temp every half second
const uint16_t Ignite_Time = 240;   //240s,上电后点火持续时间
uint8_t Ignitor_cnt = 0;
uint8_t down_temperature_selected = false;
uint8_t DisplayFirmwareVersion = 0;
uint8_t PrimingAuger = 0;
uint8_t Temp_Change_Flag = 0;
uint8_t Griddle_Flag = 0;
uint8_t Flameout_flag = 0;
uint8_t Burn_Delay_Timer = 0;
float pre_grill_temp = 0.0;
float pre_grill_griddle_temp = 0.0;
//PID专用的温度设定值
float f_SettingTemp = SmokeTempSetting; //最低PID温度设定值
#define COOLING_TIME 600                //600
uint8_t HeatingFanStep;                 //0:停止输出, >0: 进料马达工作
uint8_t ExhaustFanStep;                 //0:停止输出, >0: 排气扇工作
uint8_t IgniterStep;                    //0:停止输出, >0:点火工作

uint16_t IgniterClock; //Tick 1s
//Smoke Ctrl Variable
//Tick 10ms //2min30s = 150s = 150 * (100 * 10ms)
uint16_t HeaterFanClock; //Tick 1s
uint16_t HeaterFanStep;
uint8_t Smoke_P_Value;            //烟熏档位值:[0,5],默认0

bool first_open = true;
uint16_t ExhaustHeatingClock = 0; //马达倒计时 2min, Tick 1s, 允许数据溢出
uint8_t Open_Lid_Clock = 0;
uint16_t Open_Lid_temp[12] = {0};
uint8_t H_to_L = 0;

void FanCtrl_IOConfig(void)
{
    GPIO_Init(GPIOA0,IO_Heater,Output);
    GPIO_Init(GPIOA0,IO_Feed,Output); 
    GPIO_Init(GPIOB0,IO_Fan,Output);
}

bool Open_Lid_Check(void)
{
	if (Open_Lid_Clock>5)
	{
		for(int i=0;i<11;i++)
		{
			Open_Lid_temp[i] = Open_Lid_temp[i+1];
		}
		Open_Lid_temp[11] = grill_temperature;
		if((Open_Lid_temp[0]-Open_Lid_temp[11])>(Open_Lid_temp[0]/10))
		{
			return false;
		}
	}
	return true;
}


//温控设备上电初始化
void FanCtrlInit(void)
{
    FanCtrl_IOConfig();
    //所有温控设备默认停止输出
    IgniterClose;
    HeaterFanClose;
    ExhaustFanClose;

    Tick_1S_Count = 0;
    HeatingFanStep = 0;
    IgniterStep = 0;
    ExhaustFanStep = 0;

    HeaterFanStep = 0;
    HeaterFanClock = 0;
    ExhaustFanClock = 0;
    IgniterClock = 0;

    RTD[0].status = Pt_Normal;
}

//所有温控设备的时钟源, Tick 10ms
void FanCtrlClock(void)
{
    static uint8_t Count;



    if(Tick_10mS_Count < 0xffff) Tick_10mS_Count++;
    if((Smake_10mS_Count > 0) && (Smake_10mS_Count < 0xffff)) Smake_10mS_Count++; 
    Count++;
	millis_10ms++;
    if (Count >= 100)
    {
        Count = 0;
        if(Tick_1S_Count < 0xffff) Tick_1S_Count++; //标记产生1s计时

        if (ExhaustFanClock > 0) 
		{
			ExhaustFanClock--;
			if(ExhaustFanClock==0)
			UI_System.UI_Show = UI_OFF;
		}

        if(PowerDown_Clock > 0) PowerDown_Clock--;
        if ((IgniterClock >= 1) && (IgniterClock < 0xffff)) IgniterClock++;
        //烟熏控制相关变量
        if (HeaterFanClock < 0xffff) HeaterFanClock++;
		if (ExhaustHeatingClock > 0) ExhaustHeatingClock--;
		if (PID_T_1s > 0) PID_T_1s++;
		
		if(temp_diff<50&&temp_diff>-50&&filter_fun==1)
		{
			if(temp_set_updata > 0 && temp_set_updata < 0xffff) temp_set_updata++; //标记产生1s计时
			if (temp_filter_time < 300)
			temp_filter_time++;
		}
		else 
		{
			if (temp_filter_time > 1)
			temp_filter_time--;
		}
    }
}
//启动温控设备
void FanCtrlStart(void)
{
    if (RTD[0].status == Pt_Normal)
    { //烤炉温度正常,才能启动点火   
        if (HeatingFanStep == 0) HeatingFanStep = 1; //默认,正常温控
        if (IgniterStep == 0) IgniterStep = 1;
        if (ExhaustFanStep == 0)
        {
            ExhaustFanStep = 1;
            ExhaustFanClock = 0;
        }
    }
}
//停止温控设备
void FanCtrlStop(void)
{
    if(RTD[0].status != Pt_Normal)
    {
        ExhaustFanClock = 0;
        ExhaustFanStep = 0;
        return;
    }
	filter_fun = 0;
	temp_set_updata = 0;
	temp_filter_time = 0;
    HeatingFanStep = 0;
	if(grill_temperature>400)
	{
		H_to_L = 1;
	}
	else if(grill_temperature>300)
	{
		H_to_L = 2;
	}
	else if(grill_temperature<=300)
	{
		H_to_L = 3;
	}
	else
	{
		H_to_L = 0;
	}
    IgniterStep = 0;
    if (ExhaustFanStep > 0)
    { //排气扇打开后,才能停止排气扇
		HT162X_ResetRAM();
        ExhaustFanStep = 0;
        if(ExhaustFanClock == 0) ExhaustFanClock = FanClose_Delay_Time; //10min = 60s * 10 = 600s,多10s用于显示OFF
    }
}
//强制停止温控设备
void FanCtrlForceStop(void)
{
    HeatingFanStep = 0;
    IgniterStep = 0;
    ExhaustFanClock = 0;
    ExhaustFanStep = 0;
}

//进料控制调用该函数, 打开排气扇
void Heating_Ctrl_Exhaust_Open(void)
{
    ExhaustFanStep = 1;
}
//进料控制调用该函数, 关闭排气扇
void Heating_Ctrl_Exhaust_Close(void)
{
    ExhaustFanStep = 0;
}
void HeatingFanCtrl(void)
{
    static uint16_t start_sequence_on_time = 0;
	int32_t pid_temperature = 0;
	uint16_t pid_temp_set = 0;
	static uint16_t feed1 = 0;
	static uint16_t feed2 = 0;
    switch (HeatingFanStep)
    {
    case 0: // Close HeatingFan  
	if(H_to_L==1)
	{
		feed1 = 20;
		feed2 = 10;
	}
	else if(H_to_L==2)
	{
		feed1 = 15;
		feed2 = 5;
	}
	else if(H_to_L==3)
	{
		feed1 = 5;
		feed2 = 5;
	}
	else
	{
		feed1 = 0;
		feed2 = 0;
	}
	
	if(ExhaustFanClock>600)
	{
		HeaterFanClose;
	}
	else if(ExhaustFanClock>600-feed1)
	{
		HeaterFanOpen;
	}
	else if(ExhaustFanClock>300)
	{
		HeaterFanClose;
	}
	else if(ExhaustFanClock>300-feed2)
	{
		HeaterFanOpen;
	}
	else
	{
		HeaterFanClose;
        start_sequence_on_time = 0;
	}
	break;
    case 1:
		start_sequence_on_time = 40; //固定进料60s, 颗粒已经能够覆盖到点火针
        Tick_1S_Count = 0;
        HeatingFanStep = 2;
        HeaterFanClose;

        break;
    case 2:
        if (Tick_1S_Count == 0)
        {
            Tick_1S_Count = 1;
            HeaterFanOpen;
        }
        else if (Tick_1S_Count > start_sequence_on_time)
        {
            Tick_1S_Count = 0;
            HeaterFanClose;
            HeatingFanStep = 3;  
			
        }
        break;
    case 3:
//		if (Start_Temp > grill_temperature)
//        {
//            Start_Temp = grill_temperature;
//        }
        if (grill_temperature < 135)
        {
            if (Tick_1S_Count == 0) Tick_1S_Count = 1;
            else if (Tick_1S_Count <= 30)
            {
				if(Prime_Enable == 0)
                HeaterFanClose;
            }
            else if (Tick_1S_Count <= (30 + 5))
            {
                HeaterFanOpen;
            }
            else
            {
                Tick_1S_Count = 0;
                HeaterFanClose;
            }
        }
        else
        {
            HeaterFanClose;
            HeatingFanStep = 4;
            Tick_1S_Count = 0;
            PID_T_1s = 1;
			pid_PI.u8En = 1;
			temp_set_updata = 1;
			filter_fun = 1;
        }

        break;
        case 4:
        if (PID_T_1s >= 15)
        {
            PID_T_1s = 1;
			
            PI_Ctrl(&pid_PI, &pid_para_t,grill_temperature,temp_set);
			pid_data = (float)(pid_PI.i32Q27_Output);
            feed_stop_time = 60 - (int)pid_data;
        }
		if (Open_Lid_Check())
		{
			pid_PI.u8En = 1;
		}
		else
		{
			pid_PI.u8En = 0;
		}
        if (grill_temperature <= 135)
        {
            HeatingFanStep = 3;
        }
        else
        {
			feed_on_time =(int)pid_data*100;
        }

		feed_stop_time_int = feed_stop_time*100;
        if (millis_10ms < feed_stop_time_int)
        {
            HeaterFanClose;
        }
        else if ((feed_stop_time_int <= millis_10ms) && (millis_10ms < 60*100))                                                                                                                                                                                    
        {
            HeaterFanOpen;
        }
        else if ( millis_10ms >= 60*100)
        {
            millis_10ms = 0;
        }
       
        break;
    default:
        HeatingFanStep = 0;
        break;
    }
}


//点火控制(紫线),实际是加热棒控制
//默认上电初始化关闭所有温控输出设备
//上电点火4min后停止点火
//若温度低于150F，保持上次运行状态60s后再打开点火
//直到温度高于150F之前,始终是间隔60s后再打开点火; 目的为了防止点火点不着,或者点火异常(感觉有点多余,理论上只要CPU的IO不出问题,不太可能输出停止)
//在[150F,160F]之间,点火一直打开
//温度高于160F,停止点火(这就有问题了,温度高的情况下,停止点火,温度肯定会突然下降,难怪温度在高温很难控制)
//  补充: 在进料的时候会控制点火
//通过 SYS_STANDBY 置1, 控制停止点火
void IgniterCtrl(void)
{
    static uint8_t IgniterClock_Step = 0;

    if (RTD[0].status != Pt_Normal)
    {
        IgniterStep = 0;
    }
    switch (IgniterStep)
    {
        case 0:
            IgniterClose;
            break;
        case 1: //Stand-Bye
            IgniterOpen;
            IgniterClock = 0;
            IgniterStep = 2;
            break;
        case 2: //Ignite grilll
            if (IgniterClock == 0) IgniterClock = 1;
            else if (IgniterClock > 240)
            { //上电点火加热240s后执行
                IgniterClose;
                IgniterStep = 3; //Ignite time complete
                IgniterClock = 0;
                IgniterClock_Step = 0;
            }
            break;
        case 3: //Running
            if (grill_temperature < 150)
            { //为避免点火棒烧断: 点火棒通电后,持续时间限制在 断电2min,点火4min,
                if(IgniterClock_Step == 0)
                { //断电2min
                    if (IgniterClock == 0)
                    {
                        IgniterClose;
                        IgniterClock = 1;
                    }
                    else if (IgniterClock >= 120)
                    { 
                        IgniterClock = 0;
                        IgniterClock_Step++;
                    }
                }
                else if(IgniterClock_Step == 1)
                { //点火4min
                    if (IgniterClock == 0)
                    {
                        IgniterOpen;
                        IgniterClock = 1;
                    }
                    else if (IgniterClock >= 240)
                    {
                        IgniterClock = 0;
                        IgniterClock_Step = 0;
                    }
                }
            }
            else if (RTD[0].value > 160)
            {
                IgniterClose;
                IgniterClock_Step = 0;
                IgniterClock = 0;
            }
            break;
        default:
            IgniterStep = 0;
            break;
    }
}

//排气风扇（橙线）
//作用: 关机后,持续打开一段时间后再停止输出
//风力太大,可能需要PWM控制输出,降低风力
//系统错误,停止排气
//判断SYS_STANDBY的值,决定是否打开排气
//上电默认SYS_STANDBY为0, 排气打开
//当SYS_STANDBY == 1时, 打开排气扇持续300s后关闭排气扇
void ExhaustFanCtrl(void)
{
    if (RTD[0].status != Pt_Normal)
    {
        if (ExhaustFanStep > 0)
        { //排气扇打开后,才能停止排气扇
            ExhaustFanStep = 0;
            ExhaustFanClock = FanClose_Delay_Time; //10min = 60s * 10 = 600s,多10s用于显示OFF
            if(RTD[0].status != Pt_HighTemp) ExhaustFanClock = 0;
        }
    }
    switch (ExhaustFanStep)
    {
        case 0:
            if (ExhaustFanClock > 0)
            { //延迟10min
                ExhaustFanOpen;
                LowTemp_Ctrl = 0; //延迟低盐检测10min
            }
            else
            {//关闭排气扇
                ExhaustFanClose;
                if (first_open == false)
                { //防止 关机回火
                    if (Temp_Param.oven < 500)
                    { //低温关火
                        ExhaustHeatingClock = 30;
                        first_open = true;
                    }
                    else
                    {
                        ExhaustHeatingClock = 60;
                        first_open = true;
                    }
                }
            }
            break;
        case 1:
            ExhaustFanOpen;
            first_open = false;
            break;
        default:
            ExhaustFanStep = 0;
            break;
    }
}
